//
//  BZWCache.m
//  BaoZhangWang
//
//  Created by 叶越悦 on 15/9/30.
//  Copyright © 2015年 BaoliNetworkTechnology. All rights reserved.
//

#import "APICache.h"
#import "APIManager.h"
#import "YYYDiskCache.h"
#import "YYYMemoryCache.h"
static NSUInteger kBZWCacheCountLimit = 1000; // 最多1000条cache

@interface APICache ()

@property (nonatomic, strong) YYYMemoryCache *memoryCache;
@property (nonatomic, strong) YYYDiskCache *diskCache;/**< 文件缓存 */

@end

@implementation APICache

+ (instancetype)share {
    static dispatch_once_t onceToken;
    static APICache *sharedInstance;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[APICache alloc] init];
    });
    return sharedInstance;
}

- (instancetype)init {
    NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [cacheFolder stringByAppendingPathComponent:@"APIReformResponseObjectCache"];
    YYYDiskCache *diskCache = [[YYYDiskCache alloc] initWithPath:path];
    if (!diskCache) {
        return nil;
    }

    YYYMemoryCache *memoryCache = [[YYYMemoryCache alloc] init];
    memoryCache.countLimit = kBZWCacheCountLimit;
    if (!memoryCache) {
        return nil;
    }

    self = [super init];
    if (self) {
        _memoryCache = memoryCache;
        _diskCache = diskCache;
    }
    return self;
}

- (NSString *)cacheKeyWithManager:(id<APIManager>)manager {
    if (!manager) {
        return nil;
    }
    return manager.APICacheKey;
}

#pragma mark - public method

- (BOOL)containsObjectForManager:(id <APIManager>)manager {
    if (!manager) {
        return NO;
    }
    NSString *key = [self cacheKeyWithManager:manager];
    return [self.memoryCache containsObjectForKey:key] || [self.diskCache containsObjectForKey:key];
}

- (id)cacheObjectForManager:(id <APIManager>)manager {
    if (!manager) {
        return nil;
    }
    NSString *key = [self cacheKeyWithManager:manager];
    id cacheObj = [self.memoryCache objectForKey:key];
    if (!cacheObj) {
        cacheObj = [self.diskCache objectForKey:key];
        if (cacheObj) {
            [self.memoryCache setObject:cacheObj forKey:key];
        }
    }
    return cacheObj;
}

- (void)deleteCacheObjectForManager:(id <APIManager>)manager {
    if (!manager) {
        return;
    }
    NSString *key = [self cacheKeyWithManager:manager];
    [self.memoryCache removeObjectForKey:key];
    [self.diskCache removeObjectForKey:key];
}

- (void)cleanAllCaches {
    [self.memoryCache removeAllObjects];
    [self.diskCache removeAllObjects];
}

- (void)cleanAllCachesWithBlock:(void (^)(void))block {
    [self.memoryCache removeAllObjects];
    [self.diskCache removeAllObjectsWithBlock:block];
}

- (void)storeObject:(id)object withManager:(id <APIManager>)manager {
    if (!manager) {
        return;
    }
    if (!object) {
        [self deleteCacheObjectForManager:manager];
    }
    if (!manager.APIShouldCache) {
        return;
    }
    NSString *key = [self cacheKeyWithManager:manager];
    NSTimeInterval time = manager.APIShouldCacheInFile ? manager.APIFileCacheTimeOut : manager.APIMemoryCacheTimeOut;
    [self.memoryCache setObject:object forKey:key withExpirationTime:time];
    if (manager.APIShouldCacheInFile) {
        [self.diskCache setObject:object forKey:key withExpirationTime:time];
    }
}

@end
